<!-- MyComponent.vue -->
<template>
  <view class="container">
    <uv-form labelPosition="left" :model="model1" :rules="rules" ref="form">
      <uv-form-item label="数值" prop="datum.val" borderBottom>
        <uv-input v-model="model1.datum.val" border="none"></uv-input>
      </uv-form-item>
      <uv-form-item label="单位" prop="datum.unit" @click="showUnitSelect">
        <uv-input
          v-model="model1.datum.unit"
          disabled
          disabledColor="#ffffff"
          placeholder="请选择单位"
          border="none"
        ></uv-input>
        <template v-slot:right>
          <uv-icon name="arrow-right"></uv-icon>
        </template>
      </uv-form-item>
    </uv-form>
    <uv-divider text="转换结果"></uv-divider>
    <uv-form labelPosition="left" :model="modelResult" ref="convertResult">
      <uv-form-item
        v-for="(item, key) in modelResult"
        :key="key"
        :label="unitNames[key]"
        :prop="key"
        borderBottom
      >
        <uv-input v-model="modelResult[key]" disabled border="none"></uv-input>
      </uv-form-item>
    </uv-form>
    <uv-action-sheet
      ref="uSelect"
      :actions="actions"
      title="请选择单位"
      description=""
      @select="unitSelect"
    ></uv-action-sheet>
  </view>
</template>

<script>
export default {
  name: "LengthConverter",
  data() {
    return {
      unitNames: {
        m: "米",
        cm: "厘米",
        mm: "毫米",
        km: "千米",
        in: "英寸",
        ft: "英尺",
        yd: "码",
        mi: "英里",
        chi: "尺",
        cun: "寸",
        zhang: "丈",
        fen: "分",
        xun: "寻",
        bu: "步",
        she: "舍", // 简化处理，未提供具体转换
        yin: "引", // 简化处理，未提供具体转换
        hao: "毫", // 简化处理，未提供具体转换
        li: "厘" // 简化处理，未提供具体转换
      },
      model1: {
        datum: {
          val: "1",
          unit: "米"
        }
      },
      modelResult: {
        m: 0,
        cm: 0,
        mm: 0,
        km: 0,
        in: 0,
        ft: 0,
        yd: 0,
        mi: 0,
        chi: 0,
        cun: 0,
        zhang: 0,
        fen: 0,
        xun: 0,
        bu: 0,
        she: 0,
        yin: 0,
        hao: 0,
        li: 0
      },
      actions: [
        { name: "米" },
        { name: "厘米" },
        { name: "毫米" },
        { name: "千米" },
        { name: "英寸" },
        { name: "英尺" },
        { name: "码" },
        { name: "英里" },
        { name: "尺" },
        { name: "寸" },
        { name: "丈" },
        { name: "分" },
        { name: "寻" },
        { name: "步" },
        { name: "舍" },
        { name: "引" },
        { name: "毫" },
        { name: "厘" }
      ],
      rules: {
        "datum.val": {
          type: "number",
          required: true,
          message: "请填写数字"
        }
      }
    }
  },
  watch: {
    "model1.datum.val": function (newVal) {
      const find = Object.keys(this.unitNames).find(
        k => this.unitNames[k] == this.model1.datum.unit
      )
      this.convertAll(newVal, find)
    },
    "model1.datum.unit": function (newVal) {
      const find = Object.keys(this.unitNames).find(k => this.unitNames[k] == newVal)
      this.convertAll(this.model1.datum.val, find)
    }
  },
  methods: {
    showUnitSelect() {
      this.$refs.uSelect.open()
      this.hideKeyboard()
    },
    unitSelect(e) {
      this.model1.datum.unit = e.name
    },
    hideKeyboard() {
      uni.hideKeyboard()
    },
    convertAll(value, fromUnit) {
      for (let unitNamesKey in this.unitNames) {
        this.modelResult[unitNamesKey] = this.convertLength(value, fromUnit, unitNamesKey)
      }
    },
    convertLength(value, fromUnit, toUnit) {
      const metricToMetric = {
        m: { cm: 100, mm: 1000, km: 0.001 },
        cm: { m: 0.01, mm: 10, km: 0.00001 },
        mm: { m: 0.001, cm: 0.1, km: 0.000001 },
        km: { m: 1000, cm: 100000, mm: 1000000 }
      }

      const imperialToImperial = {
        in: { ft: 0.0833333, yd: 0.0277778, mi: 0.0000157828 },
        ft: { in: 12, yd: 0.333333, mi: 0.000189394 },
        yd: { in: 36, ft: 3, mi: 0.000568182 },
        mi: { in: 63360, ft: 5280, yd: 1760 }
      }

      const metricToImperial = {
        m: { in: 39.3701, ft: 3.28084, yd: 1.09361, mi: 0.000621371 },
        cm: { in: 0.393701, ft: 0.0328084, yd: 0.0109361, mi: 0.00000621371 },
        mm: { in: 0.0393701, ft: 0.00328084, yd: 0.00109361, mi: 0.000000621371 },
        km: { in: 39370.1, ft: 3280.84, yd: 1093.61, mi: 0.621371 }
      }

      const imperialToMetric = {
        in: { m: 0.0254, cm: 2.54, mm: 25.4, km: 0.0000254 },
        ft: { m: 0.3048, cm: 30.48, mm: 304.8, km: 0.0003048 },
        yd: { m: 0.9144, cm: 91.44, mm: 914.4, km: 0.0009144 },
        mi: { m: 1609.34, cm: 160934, mm: 1609340, km: 1.60934 }
      }

      // 添加中国传统单位转换逻辑
      const traditionalToMetric = {
        chi: { m: 0.333333, cm: 33.3333, mm: 333.333, km: 0.000333333 },
        cun: { m: 0.0333333, cm: 3.33333, mm: 33.333, km: 0.00000333333 }
      }

      const metricToTraditional = {
        m: { chi: 3, cun: 30 },
        cm: { chi: 0.333333, cun: 3.33333 },
        mm: { chi: 0.0333333, cun: 0.333333 },
        km: { chi: 3000, cun: 30000 }
      }

      let result

      if (fromUnit in metricToMetric && toUnit in metricToMetric) {
        result = value * metricToMetric[fromUnit][toUnit]
      } else if (fromUnit in imperialToImperial && toUnit in imperialToImperial) {
        result = value * imperialToImperial[fromUnit][toUnit]
      } else if (fromUnit in metricToImperial && toUnit in imperialToMetric) {
        result = value * metricToImperial[fromUnit][toUnit]
      } else if (fromUnit in imperialToMetric && toUnit in metricToImperial) {
        result = value * imperialToMetric[fromUnit][toUnit]
      } else if (fromUnit in traditionalToMetric && toUnit in metricToMetric) {
        result = value * traditionalToMetric[fromUnit][toUnit]
      } else if (fromUnit in metricToTraditional && toUnit in traditionalToMetric) {
        result = value * metricToTraditional[fromUnit][toUnit]
      } else {
        throw new Error("Unsupported conversion between " + fromUnit + " and " + toUnit)
      }

      return result
    }
  }
}
</script>

<style scoped>
.my-component {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background-color: #f0f0f0;
}

button {
  margin-top: 10px;
  padding: 5px 10px;
  border-radius: 5px;
  background-color: #007aff;
  color: white;
}
.container {
  padding: 0 15px;
}
</style>
